Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebase ABCI domain types onto main #1203

Merged
merged 29 commits into from
Sep 28, 2022
Merged

Rebase ABCI domain types onto main #1203

merged 29 commits into from
Sep 28, 2022

Conversation

mzabaluev
Copy link
Contributor

Builds on #1185 to revert some data type changes that targeted Tendermint RPC 0.35.

hdevalence and others added 22 commits September 20, 2022 13:55
Replace chrono with time 0.3 (#1030)

* pbt-gen: Converted from chrono to time 0.3

chrono has soundness issues (see RUSTSEC-2020-0159) and does not
seem to be maintained.

* Replace dependency on chrono with time 0.3

Change Time implementation to crate time: chrono has soundness issues
(see RUSTSEC-2020-0159) and does not seem to be actively maintained.

* Add Time methods checked_add and checked_sub

These should be used instead of the overloaded operators that broke
the operator convention by returning a Result.

* proto: Don't use formatting methods of time

Drop the "formatting" feature of time, as this brings in std.

* pbt-gen: Add arb_datetime_for_rfc3339

With crate time, the range of supported dates stretches to the ancient
past beyond the common era, which is not representable in RFC 3339.
Add a generator to produce `OffsetDateTime` values that are
within the RFC 3339 spec.

* Ensure Time can only have values good for RFC 3339

As the time values are meant for human-readable representation in
the RFC 3339 format, make it not possible to construct Time with values
that fall outside this standard representation.
Conversion from time::OffsetDateTime is made fallible with
a TryFrom impl replacing the From impl.
Conversion from Unix timestamps is also affected.

* rpc: Replaced chrono with time 0.3

* testgen: Replaced chrono with time 0.3

* Less allocatey ways of formatting date-times

Provide and use another helper in proto mod serializers::timestamp,
one that formats into a provided fmt::Write object rather than
allocating a string.

* light-client: port from chrono to time

* Revert to Add/Sub returning Result

* light-client: changed the MBTs from chrono to time

* tendermint: Remove a comment referencing chrono

We use ErrorDetail::DurationOutOfRange without the source error
from the time library because that is uninformative in the context.
Also move the DateOutOfRange close with DurationOutOfRange
since they can occur in the same operations and are generally similar.

* light-client: add std feature for time

The clock needs OffsetDateTime::now_utc().

* tendermint: Simplify Time::duration_since

* testgen: minor code cleanup

* Restrict valid Time years to 1-9999

Exclude year 0 because the spec on Google protobuf Timestamp forbids it.

Add more helpers in pbt-gen to produce protobuf-safe values in both
OffsetDateTime and RFC 3339 strings.

Restrict the property tests to only use the protobuf-safe values
where expected.

* Test Time::checked_add and Time::checked_sub

* Changelog entries for #1030

* Improve documentation of tendermint::Time

* proto: remove the chrono type conversions

The From impls are panicky and do not enforce compliance with
protobuf message value restrictions.

* tendermint: remove direct uses of chrono types

Replace with tendermint::Time.

* Harden Timestamp conversions and serde

Require the timestamp to be in the validity range (years 1-9999 in UTC)
and the nanosecond member value to not exceed  999_999_999.

Rename ErrorDetail::TimestampOverflow to TimestampNanosOutOfRange,
because the old variant was not very informative (the chained
TryFromIntError did not help) and we also use it for the above-range
case now which is not an overflow.

* Changelog entry about changed error variants

* Restore nanosecond range check in Time::from_unix_timestamp

Add a unit test to exercise the check.

* proto: Improve timestamp::fmt_as_rfc3339_nanos

- More ergonomic signature
- A non-allocating implementation

* Fix component name in changelog for 1030-remove-chrono

Co-authored-by: Thane Thomson <thane@informal.systems>

* time: Use Self instead of the type name in methods

Co-authored-by: Thane Thomson <thane@informal.systems>

* Comment on the inner representation of `Time`

* Don't alias crate time in testgen

* Document the Time::from_utc helper

Co-authored-by: Thane Thomson <thane@informal.systems>
The event list change did not make it into tendermint 0.37.
@codecov-commenter
Copy link

codecov-commenter commented Sep 23, 2022

Codecov Report

Merging #1203 (bd66b1e) into main (ca5a286) will decrease coverage by 3.0%.
The diff coverage is 10.6%.

❗ Current head bd66b1e differs from pull request most recent head 308d060. Consider uploading reports for the commit 308d060 to get more accurate results

@@           Coverage Diff           @@
##            main   #1203     +/-   ##
=======================================
- Coverage   67.0%   64.0%   -3.1%     
=======================================
  Files        219     250     +31     
  Lines      20706   21551    +845     
=======================================
- Hits       13892   13802     -90     
- Misses      6814    7749    +935     
Impacted Files Coverage Δ
abci/src/application.rs 18.8% <0.0%> (+0.7%) ⬆️
abci/src/client.rs 41.6% <ø> (+1.6%) ⬆️
abci/src/codec.rs 90.1% <ø> (ø)
light-client/src/evidence.rs 9.0% <ø> (ø)
light-client/src/lib.rs 100.0% <ø> (ø)
light-client/src/tests.rs 93.5% <ø> (ø)
proto/src/lib.rs 100.0% <ø> (ø)
rpc/src/abci/data.rs 90.9% <ø> (ø)
rpc/src/abci/gas.rs 67.8% <ø> (ø)
rpc/src/abci/info.rs 57.1% <ø> (ø)
... and 67 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Member

@thanethomson thanethomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mzabaluev did you perhaps rerun the proto compiler tool to generate these protos?

.changelog/unreleased/improvements/1030-new-time-api.md Outdated Show resolved Hide resolved
@mzabaluev
Copy link
Contributor Author

@mzabaluev did you perhaps rerun the proto compiler tool to generate these protos?

I tried that, the differences were superficial.

@thanethomson
Copy link
Member

Since these are going to be breaking changes, I assume we'll be targeting a v0.26.0 release with them, right? I'd recommend capturing some more detailed changelog entries for where there are breakages, e.g. the transition from Vec<u8> to Bytes in the ABCI protos.

Also don't worry about the nightly coverage breakage - it seems codecov's having an outage of some kind.

@mzabaluev
Copy link
Contributor Author

mzabaluev commented Sep 26, 2022

the transition from Vec<u8> to Bytes in the ABCI protos.

I'd actually remove this change altogether and maybe put it up for an ADR.
However, @hdevalence said in #1185 (comment) that existing users of ABCI already use it. I presume it was only true for the users of 0.24?

Comment on lines +1 to +2
- `[tendermint-proto]` Use `Bytes` for byte array fields of ABCI protobuf types.
([#1203](https://github.com/informalsystems/tendermint-rs/pull/1203))
Copy link
Contributor Author

@mzabaluev mzabaluev Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thanethomson I've added a notice about this change, but as stated already, I'm not sure we need to go ahead with it for 0.26. This is certainly unrelated to domain types, it's applied piecemeal to a single proto module not as a consistent change throughout tendermint-proto, and has the overall smell of a premature optimization.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is related to the domain types, because the ABCI domain types use Bytes internally, so unwinding this part of the ABCI domain types will break existing users of the ABCI domain types. This is not meaningfully a breaking change for anyone else, because there weren't users of the ABCI proto types other than the stub ABCI demo application. It's also not a breaking change relative to master, because this code has been merged on that branch (albeit unreleased) for about a year.

If this change is unwound out, you'll have to edit all of the ABCI domain types, and then all the users will have to edit all their uses of those domain types. I don't think it would be good to put this on the critical path for doing a semver release of the tendermint crates that contains ABCI domain types.

If the decision, later, is that the domain types should not use the Bytes type, it would be much better to do that as a later change that can be modeled with semver. (For the record, I don't think this is a good decision, but in any case I think it should be separate from getting this code backported as-is).

Copy link
Contributor Author

@mzabaluev mzabaluev Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @hdevalence for the detailed exposition.

As a late-to-the-scene comment, if I were into micro-optimizing domain type conversions to protobuf, I'd start with the Protobuf trait forcing a clone of the entire structure, because the domain-to-raw conversion is implemented via From<Self>, but the encode* methods take &self. But this is a subject for a larger rework.

@mzabaluev
Copy link
Contributor Author

'd recommend capturing some more detailed changelog entries for where there are breakages, e.g. the transition from Vec to Bytes in the ABCI protos.

Besides this (subject to discussion above) and the ABCI domain types rework that is the subject of this PR, I have removed any other breaking changes.

thanethomson
thanethomson previously approved these changes Sep 27, 2022
abci/src/codec.rs Outdated Show resolved Hide resolved
Comment on lines 116 to 120
/// Request that the application set an option to a particular value.
pub fn set_option(&mut self, req: RequestSetOption) -> Result<ResponseSetOption, Error> {
perform!(self, SetOption, req)
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal, since I don't think anyone really uses this crate, but why was set_option removed here? It's still present in Tendermint Core v0.34, and has only just been removed in v0.37. IIRC it was removed in v0.35.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this slipped through backporting. We could add it back in, or leave it out. There's no documentation on what it's actually supposed to do, so I'm not sure how anyone would use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have restored the method, but added a [deprecated] annotation to it.

Comment on lines +9 to +12
//! The old types should be eliminated and
//! merged with the new ABCI domain types. Moving them here in the meantime
//! disentangles improving the ABCI domain modeling from changes to the RPC
//! interface.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a heads-up here, I started trying to do this in #1092, but didn't have time to finish it, and then we dropped Tendermint Core v0.35.

@mzabaluev I'd recommend having this be the follow-up to this PR if you have the capacity for it. It's probably even more important than the multi-version support, because as of this PR, we effectively have some duplicate "domain type"-like structures for ABCI responses.

abci/src/client.rs Outdated Show resolved Hide resolved
@mzabaluev mzabaluev merged commit 00401ae into main Sep 28, 2022
@mzabaluev mzabaluev deleted the mikhail/abci-domain-types branch September 28, 2022 21:25
romac pushed a commit that referenced this pull request Mar 6, 2023
This reintroduces #1054 after it was removed in #1203.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants